package kz.pompei.ifacer.conf;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Config {
  private final File confFile;
  private final Map<String, String> data = new HashMap<>();
  
  public Config(File confFile) {
    this.confFile = confFile;
    read();
  }
  
  public final void read() {
    try {
      readInner();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  
  private void readInner() throws Exception {
    if (!confFile.exists()) return;
    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(confFile),
        "UTF-8"));
    String line = null;
    while ((line = br.readLine()) != null) {
      if (line.trim().startsWith("#")) continue;
      int idx = line.indexOf('=');
      if (idx < 0) continue;
      String key = line.substring(0, idx).trim();
      String value = line.substring(idx + 1).trim();
      data.put(key, value);
    }
    br.close();
  }
  
  public String get(String name) {
    String ret = data.get(name);
    if (ret == null) return "";
    return ret;
  }
  
  public void remove(String name) {
    data.remove(name);
  }
  
  public void set(String name, String value) {
    data.put(name, value);
  }
  
  public void write() {
    try {
      writeInner();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  
  private void writeInner() throws Exception {
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    {
      PrintStream out = new PrintStream(bout, false, "UTF-8");
      
      final Set<String> addedNames = new HashSet<>();
      
      if (confFile.exists()) {
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(confFile),
            "UTF-8"));
        String line = null;
        while ((line = br.readLine()) != null) {
          if (line.trim().startsWith("#")) {
            out.println(line);
            continue;
          }
          int idx = line.indexOf('=');
          if (idx < 0) {
            out.println(line);
            continue;
          }
          String key = line.substring(0, idx);
          if (!data.containsKey(key.trim())) continue;
          String value = line.substring(idx + 1);
          String newValue = data.get(key.trim());
          
          StringBuilder sb = new StringBuilder();
          sb.append(key).append('=');
          if (!newValue.startsWith(" ")) {
            for (int i = 0; i < value.length(); i++) {
              char c = value.charAt(i);
              if (c != ' ') break;
              sb.append(' ');
            }
          }
          sb.append(newValue);
          out.println(sb.toString());
          addedNames.add(key.trim());
        }
        br.close();
      }
      
      List<String> keys = new ArrayList<>();
      keys.addAll(data.keySet());
      Collections.sort(keys);
      
      for (String name : keys) {
        if (addedNames.contains(name)) continue;
        out.println(name + " = " + data.get(name));
      }
      
      out.close();
    }
    
    {
      confFile.getParentFile().mkdirs();
      FileOutputStream out = new FileOutputStream(confFile);
      out.write(bout.toByteArray());
      out.close();
    }
  }
  
  public void setInt(String name, int value) {
    set(name, "" + value);
  }
  
  public int getInt(String name, int defaultValue) {
    String s = get(name);
    try {
      return Integer.parseInt(s);
    } catch (NumberFormatException e) {
      return defaultValue;
    }
  }
  
  public int getInt(String name) {
    return getInt(name, 0);
  }
}
